#include <Communication.h>

Communication::Communication()
{
	
}
Communication::Communication(MCP2510 can_dev, Canutil canutil)
{
	this->can_dev = &can_dev;
	this->canutil = &canutil;
	this->canutil->flashRxbf();  //just for fun make the DEL flash
	this->can_dev->write(CANINTE,0x01);  //disables all interrupts but RX0IE (received message in RX buffer 0)
	this->can_dev->write(CANINTF, 0x00);  // Clears all interrupts flags

	this->canutil->setClkoutMode(0,0);  // disables CLKOUT
	this->canutil->setTxnrtsPinMode(0,0,0);  // all TXnRTS pins as all-purpose digital input

	this->canutil->setOpMode(4); // sets configuration mode

	this->canutil->waitOpMode(4);  // waits configuration mode

	this->can_dev->write(CNF1,0x03);  // SJW = 1, BRP = 3
	this->can_dev->write(CNF2,0b10110001);  //BLTMODE = 1, SAM = 0, PHSEG = 6, PRSEG = 1
	this->can_dev->write(CNF3, 0x05);  // WAKFIL = 0, PHSEG2 = 5

	this->canutil->setOpMode(0); // sets normal mode 
	this->opmode = this->canutil->whichOpMode();

	this->canutil->setTxBufferDataLength(0,1,0);   // TX normal data, 1 byte long, with buffer 0

	for (int i = 0; i<8; i++)
	{  
		this->tosend[i] = 0;
		this->data[i] = 0;
	}

	for (int i = 0; i<6; i++)
	{  
		this->filter[i] = 0;
	}

	this-> flagReceivedData = 0;

	this->finalizeFilter();

	this->can_dev->write(CANINTF, 0x00);  // Clears all interrupts flags
}

void Communication::setFilter(uint16_t filter,int id)
{
	if(id < 6)
	{
		this->filter[id] = filter;
	}
}

void Communication::sendData(uint8_t data[8],uint16_t id, uint8_t priority)
{
	this->canutil->setTxBufferID(id,2000,0,0);
	this->canutil->setTxBufferDataField(data, 0);
	this->canutil->messageTransmitRequest(0,1,priority);
	do 
	{
		txstatus = 0;
		txstatus = canutil->isTxError(0);  // checks tx error
		txstatus = txstatus + canutil->isArbitrationLoss(0);  // checks for arbitration loss
		txstatus = txstatus + canutil->isMessageAborted(0);  // ckecks for message abort
		txstatus = txstatus + canutil->isMessagePending(0);   // checks transmission
	} 
	while (txstatus != 0); // waits for no error condition
}

void Communication::received()
{
	this->flagReceivedData = 1;
	can_dev->write(CANINTF, 0x00);  // Clears all interrupts flags

	int recSize = canutil->whichRxDataLength(0);  // checks the number of bytes received in buffer 0 (max = 8)

	for (int i=0; i<recSize; i++) // gets the bytes
	{  
		this->data[i] = canutil->receivedDataValue(0,i);
	}
}

 uint8_t* Communication::getData()
{
	return this->data;
}

int Communication::getFlagReceivedData()
{
	return this->flagReceivedData;
}

void Communication::finalizeFilter()
{
	canutil->setRxOperatingMode(1, 1, 0);
	for(int i = 0; i < 6 ;i++)
	{
		canutil->setAcceptanceFilter(filter[i], 2000 + i, 0, i);
	}
	canutil->setAcceptanceMask(0xFFFF, 0x00000000, 0);
}